home *** CD-ROM | disk | FTP | other *** search
- ;This is a simple boot sector that will load either MS-DOS or PC-DOS. It is not
-
- ;self-reproducing, but it will be used as the foundation on which to build a
-
- ;virus into a boot sector.
-
-
-
- ;This segment is where the first operating system file (IBMBIO.COM or IO.SYS)
-
- ;will be loaded and executed from. We don't know (or care) what is there, but
-
- ;we do need the address to jump to defined in a separate segment so we can
-
- ;execute a far jump to it.
-
- DOS_LOAD SEGMENT AT 0070H
-
- ASSUME CS:DOS_LOAD
-
-
-
- ORG 0
-
-
-
- LOAD: DB 0 ;Start of the first operating system program
-
-
-
- DOS_LOAD ENDS
-
-
-
-
-
- MAIN SEGMENT BYTE
-
- ASSUME CS:MAIN,DS:MAIN,SS:NOTHING
-
-
-
- ;This jump instruction is just here so we can compile this program as a COM
-
- ;file. It is never actually executed, and never becomes a part of the boot
-
- ;sector. Only the 512 bytes after the address 7C00 in this file become part of
-
- ;the boot sector.
-
- ORG 100H
-
-
-
- START: jmp BOOTSEC
-
-
-
- ;The following two definitions are BIOS RAM bytes which contain information
-
- ;about the number and type of disk drives in the computer. These are needed by
-
- ;the virus to decide on where to look to find drives to infect. They are not
-
- ;normally needed by an ordinary boot sector.
-
- ;
-
- ; ORG 0410H
-
- ;
-
- ;SYSTEM_INFO: DB ? ;System info byte: Take bits 6 & 7 and add 1 to get number of
-
- ; ;disk drives on this system (eg 01 = 2 drives)
-
- ;
-
- ; ORG 0475H
-
- ;
-
- ;HD_COUNT: DB ? ;Number of hard drives in the system
-
- ;
-
- ;This area is reserved for loading the first sector of the root directory, when
-
- ;checking for the existence of system files and loading the first system file.
-
-
-
- ORG 0500H
-
-
-
- DISK_BUF: DW ? ;Start of the buffer
-
-
-
- ;Here is the start of the boot sector code. This is the chunk we will take out
-
- ;of the compiled COM file and put it in the first sector on a 360K floppy disk.
-
- ;Note that this MUST be loaded onto a 360K floppy to work, because the
-
- ;parameters in the data area that follow are set up to work only with a 360K
-
- ;disk!
-
-
-
- ORG 7C00H
-
-
-
- BOOTSEC: JMP BOOT ;Jump to start of boot sector code
-
-
-
- ORG 7C03H ;This is needed because the jump will get coded as 2 bytes
-
-
-
- DOS_ID: DB 'EZBOOT ' ;Name of this boot sector (8 bytes)
-
- SEC_SIZE: DW 200H ;Size of a sector, in bytes
-
- SECS_PER_CLUST: DB 02 ;Number of sectors in a cluster
-
- FAT_START: DW 1 ;Starting sector for the first File Allocation Table (FAT)
-
- FAT_COUNT: DB 2 ;Number of FATs on this disk
-
- ROOT_ENTRIES: DW 70H ;Number of root directory entries
-
- SEC_COUNT: DW 2D0H ;Total number of sectors on this disk
-
- DISK_ID: DB 0FDH ;Disk type code (This is 360KB)
-
- SECS_PER_FAT: DW 2 ;Number of sectors per FAT
-
- SECS_PER_TRK: DW 9 ;Sectors per track for this drive
-
- HEADS: DW 2 ;Number of heads (sides) on this drive
-
- HIDDEN_SECS: DW 0 ;Number of hidden sectors on the disk
-
-
-
- DSKBASETBL:
-
- DB 0 ;Specify byte 1: step rate time, head unload time
-
- DB 0 ;Specify byte 2: Head load time, DMA mode
-
- DB 0 ;Wait time until motor turned off, in clock ticks
-
- DB 0 ;Bytes per sector (0=128, 1=256, 2=512, 3=1024)
-
- DB 12H ;Last sector number (we make it large enough to handle 1.2/1.44 MB floppies)
-
- DB 0 ;Gap length between sectors for r/w operations, in bytes
-
- DB 0 ;Data transfer length when sector length not specified
-
- DB 0 ;Gap length between sectors for format operations, in bytes
-
- DB 0 ;Value stored in newly formatted sectors
-
- DB 1 ;Head settle time, in milliseconds (we set it small to speed operations)
-
- DB 0 ;Motor startup time, in 1/8 seconds
-
-
-
- HEAD: DB 0 ;Current head to read from (scratch area used by boot sector)
-
-
-
- ;Here is the start of the boot sector code
-
-
-
- BOOT: CLI ;interrupts off
-
- XOR AX,AX ;prepare to set up segments
-
- MOV ES,AX ;set ES=0
-
- MOV SS,AX ;start stack at 0000:7C00
-
- MOV SP,OFFSET BOOTSEC
-
- MOV BX,1EH*4 ;get address of disk
-
- LDS SI,SS:[BX] ;param table in ds:si
-
- PUSH DS
-
- PUSH SI ;save that address
-
- PUSH SS
-
- PUSH BX ;and its address
-
-
-
- MOV DI,OFFSET DSKBASETBL ;and update default
-
- MOV CX,11 ;values to the table stored here
-
- CLD ;direction flag cleared
-
- DFLT1: LODSB
-
- CMP BYTE PTR ES:[DI],0 ;anything non-zero
-
- JNZ SHORT DFLT2 ;is not a default, so don't save it
-
- STOSB ;else put default value in place
-
- JMP SHORT DFLT3 ;and go on to next
-
- DFLT2: INC DI
-
- DFLT3: LOOP DFLT1 ;and loop until cx=0
-
-
-
- MOV AL,AH ;set ax=0
-
- MOV DS,AX ;set ds=0 so we can set disk tbl
-
- MOV WORD PTR [BX+2],AX ;to @DSKBASETBL (ax=0 here)
-
- MOV WORD PTR [BX],OFFSET DSKBASETBL ;ok, done
-
- STI ;now turn interrupts on
-
- INT 13H ;and reset disk drive system
-
- ERROR1: JC ERROR1 ;if an error, hang the machine
-
-
-
- ;Here we look at the first file on the disk to see if it is the first MS-DOS or
-
- ;PC-DOS system file, IO.SYS or IBMBIO.COM, respectively.
-
- LOOK_SYS:
-
- MOV AL,BYTE PTR [FAT_COUNT] ;get fats per disk
-
- XOR AH,AH
-
- MUL WORD PTR [SECS_PER_FAT] ;multiply by sectors per fat
-
- ADD AX,WORD PTR [HIDDEN_SECS] ;add hidden sectors
-
- ADD AX,WORD PTR [FAT_START] ;add starting fat sector
-
-
-
- PUSH AX
-
- MOV WORD PTR [DOS_ID],AX ;root dir, save it
-
-
-
- MOV AX,20H ;dir entry size
-
- MUL WORD PTR [ROOT_ENTRIES] ;dir size in ax
-
- MOV BX,WORD PTR [SEC_SIZE] ;sector size
-
- ADD AX,BX ;add one sector
-
- DEC AX ;decrement by 1
-
- DIV BX ;ax=# sectors in root dir
-
- ADD WORD PTR [DOS_ID],AX ;DOS_ID=start of data
-
- MOV BX,OFFSET DISK_BUF ;set up disk read buffer at 0000:0500
-
- POP AX
-
- CALL CONVERT ;and go convert sequential sector number to bios data
-
- MOV AL,1 ;prepare for a disk read for 1 sector
-
- CALL READ_DISK ;go read it
-
-
-
- MOV DI,BX ;compare first file on disk with
-
- MOV CX,11 ;required file name
-
- MOV SI,OFFSET SYSFILE_1 ;of first system file for PC DOS
-
- REPZ CMPSB
-
- JZ SYSTEM_THERE ;ok, found it, go load it
-
-
-
- MOV DI,BX ;compare first file with
-
- MOV CX,11 ;required file name
-
- MOV SI,OFFSET SYSFILE_2 ;of first system file for MS DOS
-
- REPZ CMPSB
-
- ERROR2: JNZ ERROR2 ;not the same - an error, so hang the machine
-
-
-
- ;Ok, system file is there, so load it
-
- SYSTEM_THERE:
-
- MOV AX,WORD PTR [DISK_BUF+1CH] ;get file size of IBMBIO.COM/IO.SYS
-
- XOR DX,DX
-
- DIV WORD PTR [SEC_SIZE] ;and divide by sector size
-
- INC AL ;ax=number of sectors to read
-
- MOV BP,AX ;store that number in BP
-
- MOV AX,WORD PTR [DOS_ID] ;get sector number of start of data
-
- PUSH AX
-
- MOV BX,700H ;set disk read buffer to 0000:0700
-
- RD_BOOT1: MOV AX,WORD PTR [DOS_ID] ;and get sector to read
-
- CALL CONVERT ;convert to bios Trk/Cyl/Sec info
-
- MOV AL,1 ;read one sector
-
- CALL READ_DISK ;go read the disk
-
- SUB BP,1 ;subtract 1 from number of sectors to read
-
- JZ DO_BOOT ;and quit if we're done
-
- ADD WORD PTR [DOS_ID],1 ;add sectors read to sector to read
-
- ADD BX,WORD PTR [SEC_SIZE] ;and update buffer address
-
- JMP RD_BOOT1 ;then go for another
-
-
-
-
-
- ;Ok, the first system file has been read in, now transfer control to it
-
- DO_BOOT:
-
- MOV CH,BYTE PTR [DISK_ID] ;Put drive type in ch
-
- MOV DL,BYTE PTR [DRIVE] ;Drive number in dl
-
- POP BX
-
- JMP FAR PTR LOAD ;and transfer control to the first system file
-
-
-
-
-
- ;Convert sequential sector number in ax to BIOS Track, Head, Sector information.
-
- ;Save track number in DX, sector number in CH,
-
- CONVERT:
-
- XOR DX,DX
-
- DIV WORD PTR [SECS_PER_TRK] ;divide ax by sectors per track
-
- INC DL ;dl=sector number to start read on, al=track/head count
-
- MOV CH,DL ;save it here
-
- XOR DX,DX
-
- DIV WORD PTR [HEADS] ;divide ax by head count
-
- MOV BYTE PTR [HEAD],DL ;dl=head number, save it
-
- MOV DX,AX ;ax=track number, save it in dx
-
- RET
-
-
-
-
-
- ;Read the disk for the number of sectors in al, into the buffer es:bx, using
-
- ;the track number in DX, the head number at HEAD, and the sector
-
- ;number at CH.
-
- READ_DISK:
-
- MOV AH,2 ;read disk command
-
- MOV CL,6 ;shift possible upper 2 bits of track number to
-
- SHL DH,CL ;the high bits in dh
-
- OR DH,CH ;and put sector number in the low 6 bits
-
- MOV CX,DX
-
- XCHG CH,CL ;ch (0-5) = sector, cl, ch (6-7) = track
-
- MOV DL,BYTE PTR [DRIVE] ;get drive number from here
-
- MOV DH,BYTE PTR [HEAD] ;and head number from here
-
- INT 13H ;go read the disk
-
- ERROR3: JC ERROR3 ;hang in case of an error
-
- RET
-
-
-
- ;Move data that doesn't change from this boot sector to the one read in at
-
- ;DISK_BUF. That includes everything but the DRIVE ID (at offset 7DFDH) and
-
- ;the data area at the beginning of the boot sector.
-
- MOVE_DATA:
-
- MOV SI,OFFSET DSKBASETBL ;Move all of the boot sector code after the data area
-
- MOV DI,OFFSET DISK_BUF + (OFFSET DSKBASETBL - OFFSET BOOTSEC)
-
- MOV CX,OFFSET DRIVE - OFFSET DSKBASETBL
-
- REP MOVSB
-
- MOV SI,OFFSET BOOTSEC ;Move the initial jump and the sector ID
-
- MOV DI,OFFSET DISK_BUF
-
- MOV CX,11
-
- REP MOVSB
-
- RET
-
-
-
-
-
- SYSFILE_1: DB 'IBMBIO COM' ;PC DOS System file
-
- SYSFILE_2: DB 'IO SYS' ;MS DOS System file
-
-
-
- ORG 7DFDH
-
-
-
- DRIVE: DB 0 ;Drive number, used in disk reads, etc.
-
- BOOT_ID: DW 0AA55H ;Boot sector ID word
-
-
-
-
-
- MAIN ENDS
-
-
-
-
-
- END START
-